from PySide2.QtWidgets import QTableWidgetItem,QMessageBox,QFileDialog
from PySide2.QtUiTools import QUiLoader
from PySide2.QtCore import Qt
import pyqtgraph as pg

from share import SI, mySignals

import json,os,traceback,sys,time,re

from functools import partial

from lib.syntaxhighlighter import PythonHighlighter

class Monitor:

    def __init__(self):

        # 从文件中加载UI定义

        self.ui_loader = QUiLoader()

        self.ui = self.ui_loader.load('ui/monitor.ui')

        self.ui.splitter.setSizes([500, 500])

        self.ui.action_plotPerf.triggered.connect(self.action_plotPerf)
        mySignals.stats_recved.connect(self.stats_recved)

        for row in range(10):
            for col in range(7):
                item = QTableWidgetItem('')
                item.setFlags(Qt.ItemIsEnabled) # 参数名字段不允许修改
                item.setTextAlignment(Qt.AlignCenter)
                self.ui.table_sps.setItem(row, col, item)

        # 保存 表格控件 里面的 数据
        self.statsInfoList = []

        self.setPlotWidget()


    def setPlotWidget(self):
        # 创建 PlotWidget 对象
        self.pw = pg.PlotWidget()
        # 背景色改为白色
        self.pw.setBackground('w')

        # 显示表格线
        self.pw.showGrid(x=True, y=True)
        self.pw.setMouseEnabled(x=False,y=False)

        # 设置图表标题
        self.pw.setTitle("请求响应数量", color='008080', size='12pt')

        # 设置上下左右的label
        self.pw.setLabel("left", "单位(个)")

        # 实时显示应该获取 PlotDataItem 对象, 调用其setData方法，
        # 这样只重新plot该曲线，性能更高
        self.pdi_rps = self.pw.plot(pen=pg.mkPen('r', width=1))
        self.pdi_tps = self.pw.plot(pen=pg.mkPen('g', width=1))


        # 创建 绘图对象2
        self.pw2 = pg.PlotWidget()
        self.pw2.setBackground('w')
        self.pw2.showGrid(x=True, y=True)
        self.pw2.setMouseEnabled(x=False,y=False)
        self.pw2.setTitle("响应时长",color='008080',size='12pt')
        self.pw2.setLabel("left","单位：秒")
        self.pdi_latency = self.pw2.plot(pen=pg.mkPen('#4682B4'))

        # 添加 PlotWidget 对象到 界面layout中
        self.ui.layout_plots.addWidget(self.pw)
        self.ui.layout_plots.addWidget(self.pw2)


        self.plotData_xticks = []
        self.plotData_rps = []
        self.plotData_tps = []
        self.plotData_latency = []


    def stats_recved(self,recvStr):
        stats = json.loads(recvStr)

        record = []

        timestamp = time.strftime('%M:%S',time.localtime(stats['t']))
        record.append(timestamp)

        rps = stats['rps']
        record.append(f"{rps} | {stats['total'].pop('send')}")

        tps = stats['tps']
        record.append(f"{tps} | {stats['total'].pop('recv')}")

        tops = stats['tops']
        total_timeout = stats['total'].pop('timeout') if 'timeout' in stats['total'] else 0
        record.append(f"{tops} | {total_timeout}")

        eps = stats['eps']
        total_error = stats['total'].pop('error') if 'error' in stats['total'] else 0
        record.append(f"{eps} | {total_error}")

        latency = stats['avgRespTime']
        record.append(f"{latency:.4f}")

        record.append(' | '.join([f'{k}:{v}' for k,v in stats['total'].items()]))

        self.statsInfoList.insert(0,record)


        # 曲线图数据保存
        self.plotData_xticks.append(timestamp)
        self.plotData_rps.append(rps)
        self.plotData_tps.append(tps)
        self.plotData_latency.append(latency)


        # 如果到达11次记录
        if len(self.statsInfoList) == 11:
            self.statsInfoList.pop(10)

            self.plotData_xticks.pop(0)
            self.plotData_rps.pop(0)
            self.plotData_tps.pop(0)
            self.plotData_latency.pop(0)


        # 更新表格
        for row in range(len(self.statsInfoList)):
            for col in range(7):
                self.ui.table_sps.item(row,col).setText(self.statsInfoList[row][col])

        # 更新曲线图
        xTick = [[(idx, tick) for idx,tick in enumerate(self.plotData_xticks)]]

        xax = self.pw.getAxis('bottom')
        xax.setTicks(xTick)

        xserial = range(len(self.plotData_rps))

        self.pdi_rps.setData(xserial,self.plotData_rps)
        self.pdi_tps.setData(xserial,self.plotData_tps)

        xax2 = self.pw2.getAxis('bottom')
        xax2.setTicks(xTick)
        self.pdi_latency.setData(xserial,self.plotData_latency)


    def action_plotPerf(self):

        filePaths, _ = QFileDialog.getOpenFileNames(
            self.ui,  # 父窗口对象
            "选择数据文件",  # 标题
            SI.projectPath,  # 起始目录
            "统计数据 (*.sts)"  # 选择类型过滤项，过滤内容在括号中
        )

        if not filePaths:
            return

        nl = ','.join([f"r'{fp}'" for fp in filePaths])
        code = f'''from hyload.tools.plotperf import ps; ps([{nl}])'''

        cmd = f'start call "{sys.executable}" -c "{code}"'
        SI.logInfo(f'作图：{cmd}')
        os.system(cmd)









